package com.zt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zt.entity.Coupons;
import com.zt.entity.UserCoupons;
import com.zt.mapper.CouponsMapper;
import com.zt.mapper.UserCouponsMapper;
import com.zt.service.AdminLogService;
import com.zt.service.CouponDistributionRedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.zt.constant.SystemConstants.*;

/**
 * Redis键常量
 */
class RedisConstants {
    public static final String COUPONS_KEY = "coupons:";
    public static final int NEW_USER_COUPON_TTL = 6; // 6天
}

/**
 * 优惠券发放Redis服务实现类
 * 按照指定格式实现优惠券发放和缓存
 */
@Service
@Slf4j
public class CouponDistributionRedisServiceImpl implements CouponDistributionRedisService {
    
    @Autowired
    @Qualifier("couponRedisTemplate")
    private StringRedisTemplate couponRedisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Autowired
    private CouponsMapper couponsMapper;
    
    @Autowired
    private UserCouponsMapper userCouponsMapper;
    
    @Autowired
    private AdminLogService adminLogService;
    
    /**
     * 为新用户发放默认优惠券（参考您提供的代码风格）
     * @param userId 用户ID
     */
    public void giveNewUserCoupon(Long userId) {
        try {
            // 1. 获取ID为DEFAULT_COUPON_ID的优惠券
            Integer defaultCouponId = 1; // 默认优惠券ID
            Coupons coupon = couponsMapper.selectById(defaultCouponId);
            if (coupon == null) {
                log.warn("默认优惠券不存在，ID: {}", defaultCouponId);
                return;
            }

            // 2. 检查用户是否已经拥有该优惠券
            if (hasUserCoupon(userId, defaultCouponId)) {
                log.info("用户 {} 已拥有优惠券 {}，跳过发放", userId, defaultCouponId);
                return;
            }

            // 3. 创建用户优惠券记录
            UserCoupons userCoupon = new UserCoupons();
            userCoupon.setUserId(userId.intValue());
            userCoupon.setCouponId(defaultCouponId);
            userCoupon.setStatus(1); // 1表示未使用
            userCoupon.setCreatedAt(new Date());
            
            userCouponsMapper.insert(userCoupon);
            
            // 4. 将优惠券列表存储到Redis，使用指定的JSON格式
            List<Coupons> couponsList = new ArrayList<>();
            couponsList.add(coupon);

            String couponsKey = RedisConstants.COUPONS_KEY + userId;
            String couponsJson = objectMapper.writeValueAsString(convertCouponsToRequiredFormat(couponsList));
            long expireSeconds = calculateCouponExpireTime(coupon);
            couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, expireSeconds, TimeUnit.SECONDS);
            
            log.info("新用户 {} 注册成功，已自动发放优惠券，ID: {}", userId, defaultCouponId);
            
        } catch (Exception e) {
            log.error("为新用户 {} 发放优惠券失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 为用户发放指定优惠券
     * @param userId 用户ID
     * @param couponId 优惠券ID
     */
    @Transactional
    public void distributeCouponToUser(Long userId, Integer couponId) {
        try {
            // 1. 获取优惠券信息
            Coupons coupon = couponsMapper.selectById(couponId);
            if (coupon == null) {
                log.warn("优惠券不存在，ID: {}", couponId);
                return;
            }
            
            // 2. 检查用户是否已经拥有该优惠券
            if (hasUserCoupon(userId, couponId)) {
                log.info("用户 {} 已拥有优惠券 {}，跳过发放", userId, couponId);
                return;
            }
            
            // 3. 创建用户优惠券记录
            UserCoupons userCoupon = new UserCoupons();
            userCoupon.setUserId(userId.intValue());
            userCoupon.setCouponId(couponId);
            userCoupon.setStatus(1); // 1表示未使用
            userCoupon.setCreatedAt(new Date());
            
            userCouponsMapper.insert(userCoupon);
            
            // 4. 更新Redis缓存
            updateUserCouponsCache(userId, coupon);
            
            log.info("用户 {} 成功获得优惠券，ID: {}", userId, couponId);
            
        } catch (Exception e) {
            log.error("为用户 {} 发放优惠券 {} 失败: {}", userId, couponId, e.getMessage(), e);
        }
    }
    
    /**
     * 通用发放优惠券方法
     * 使用 couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, RedisConstants.NEW_USER_COUPON_TTL, TimeUnit.DAYS)
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @param source 发放来源（如：新用户注册、活动发放、管理员发放等）
     */
    @Transactional
    public void distributeCouponWithRedisCache(Long userId, Integer couponId, String source) {
        try {
            // 1. 获取优惠券信息
            Coupons coupon = couponsMapper.selectById(couponId);
            if (coupon == null) {
                log.warn("优惠券不存在，ID: {}", couponId);
                return;
            }

            // 2. 检查优惠券状态
            if (coupon.getStatus() != 1) {
                log.warn("优惠券未激活，ID: {}, 状态: {}", couponId, coupon.getStatus());
                return;
            }

            // 3. 检查用户是否已经拥有该优惠券
            if (hasUserCoupon(userId, couponId)) {
                log.info("用户 {} 已拥有优惠券 {}，跳过发放", userId, couponId);
                return;
            }

            // 4. 创建用户优惠券记录
            UserCoupons userCoupon = new UserCoupons();
            userCoupon.setUserId(userId.intValue());
            userCoupon.setCouponId(couponId);
            userCoupon.setStatus(1); // 1表示未使用
            userCoupon.setCreatedAt(new Date());

            userCouponsMapper.insert(userCoupon);

            // 5. 获取用户当前所有优惠券
            List<Coupons> userCoupons = getUserAllCouponsFromDB(userId);

            // 6. 将完整的优惠券列表存储到Redis，使用指定的JSON格式
            String couponsKey = RedisConstants.COUPONS_KEY + userId;
            String couponsJson = objectMapper.writeValueAsString(convertCouponsToRequiredFormat(userCoupons));
            long expireSeconds = calculateOptimalExpireTime(userCoupons);
            couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, expireSeconds, TimeUnit.SECONDS);

            log.info("用户 {} 成功获得优惠券，ID: {}，来源: {}，已更新Redis缓存", userId, couponId, source);

        } catch (Exception e) {
            log.error("为用户 {} 发放优惠券 {} 失败，来源: {}: {}", userId, couponId, source, e.getMessage(), e);
            throw new RuntimeException("发放优惠券失败", e);
        }
    }

    /**
     * 活动发放优惠券
     * 专门用于活动场景的优惠券发放，使用Redis缓存
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @param activityName 活动名称
     */
    @Transactional
    public void distributeActivityCoupon(Long userId, Integer couponId, String activityName) {
        try {
            // 1. 获取优惠券信息
            Coupons coupon = couponsMapper.selectById(couponId);
            if (coupon == null) {
                log.warn("活动优惠券不存在，ID: {}", couponId);
                return;
            }

            // 2. 检查优惠券是否激活
            if (coupon.getStatus() != 1) {
                log.warn("活动优惠券未激活，ID: {}, 状态: {}", couponId, coupon.getStatus());
                return;
            }

            // 3. 检查用户是否已经拥有该优惠券
            if (hasUserCoupon(userId, couponId)) {
                log.info("用户 {} 已拥有活动优惠券 {}，跳过发放", userId, couponId);
                return;
            }

            // 4. 创建用户优惠券记录
            UserCoupons userCoupon = new UserCoupons();
            userCoupon.setUserId(userId.intValue());
            userCoupon.setCouponId(couponId);
            userCoupon.setStatus(1); // 1表示未使用
            userCoupon.setCreatedAt(new Date());

            userCouponsMapper.insert(userCoupon);

            // 5. 获取用户当前所有优惠券
            List<Coupons> userCoupons = getUserAllCouponsFromDB(userId);

            // 6. 使用指定的Redis格式存储优惠券列表，设置动态过期时间
            String couponsKey = RedisConstants.COUPONS_KEY + userId;
            String couponsJson = objectMapper.writeValueAsString(convertCouponsToRequiredFormat(userCoupons));
            long expireSeconds = calculateOptimalExpireTime(userCoupons);
            couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, expireSeconds, TimeUnit.SECONDS);

            // 7. 记录活动日志
            String logDescription = String.format("活动发放优惠券：%s，活动：%s", coupon.getTitle(), activityName);
            adminLogService.saveLog(null, "system", "优惠券管理", "活动发放", logDescription,
                "ACTIVITY", "/system/activity-distribute-coupon",
                String.format("userId=%d,couponId=%d,activity=%s", userId, couponId, activityName),
                "发放成功", 1, null, "127.0.0.1", "System", 0L);

            log.info("用户 {} 成功获得活动优惠券，ID: {}，活动: {}，已更新Redis缓存", userId, couponId, activityName);

        } catch (Exception e) {
            log.error("为用户 {} 发放活动优惠券 {} 失败，活动: {}: {}", userId, couponId, activityName, e.getMessage(), e);
            throw new RuntimeException("发放活动优惠券失败", e);
        }
    }

    /**
     * 批量发放优惠券
     * @param userIds 用户ID列表
     * @param couponId 优惠券ID
     */
    @Transactional
    public void batchDistributeCoupons(List<Integer> userIds, Integer couponId) {
        try {
            // 1. 获取优惠券信息
            Coupons coupon = couponsMapper.selectById(couponId);
            if (coupon == null) {
                log.warn("优惠券不存在，ID: {}", couponId);
                return;
            }
            
            int successCount = 0;
            int skipCount = 0;
            
            for (Integer userId : userIds) {
                try {
                    // 检查用户是否已经拥有该优惠券
                    if (hasUserCoupon(userId.longValue(), couponId)) {
                        skipCount++;
                        continue;
                    }
                    
                    // 创建用户优惠券记录
                    UserCoupons userCoupon = new UserCoupons();
                    userCoupon.setUserId(userId);
                    userCoupon.setCouponId(couponId);
                    userCoupon.setStatus(1); // 1表示未使用
                    userCoupon.setCreatedAt(new Date());
                    
                    userCouponsMapper.insert(userCoupon);
                    
                    // 更新Redis缓存
                    updateUserCouponsCache(userId.longValue(), coupon);
                    
                    successCount++;
                    
                } catch (Exception e) {
                    log.error("为用户 {} 发放优惠券失败: {}", userId, e.getMessage());
                    skipCount++;
                }
            }
            
            // 记录操作日志
            String logDescription = String.format("批量发放优惠券：%s，成功发放%d张，跳过%d张",
                coupon.getTitle(), successCount, skipCount);
            adminLogService.saveLog(null, "system", "优惠券管理", "批量发放", logDescription,
                "BATCH", "/system/batch-distribute-coupon", userIds.toString(),
                "发放完成", 1, null, "127.0.0.1", "System", 0L);
            
            log.info("批量发放优惠券完成：优惠券ID={}, 成功{}张, 跳过{}张", couponId, successCount, skipCount);
            
        } catch (Exception e) {
            log.error("批量发放优惠券失败：优惠券ID={}", couponId, e.getMessage(), e);
        }
    }
    
    /**
     * 获取用户的优惠券缓存
     * @param userId 用户ID
     * @return 用户优惠券列表（Map格式）
     */
    public List<Map<String, Object>> getUserCouponsFromCache(Long userId) {
        try {
            String couponsKey = RedisConstants.COUPONS_KEY + userId;
            String couponsJson = couponRedisTemplate.opsForValue().get(couponsKey);

            if (couponsJson != null && !couponsJson.isEmpty()) {
                List<Map<String, Object>> coupons = objectMapper.readValue(
                    couponsJson,
                    objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)
                );
                return coupons;
            }
        } catch (Exception e) {
            log.error("获取用户 {} 的优惠券缓存失败: {}", userId, e.getMessage(), e);
        }
        return new ArrayList<>();
    }
    
    /**
     * 删除用户优惠券缓存
     * @param userId 用户ID
     */
    public void deleteUserCouponsCache(Long userId) {
        try {
            String couponsKey = RedisConstants.COUPONS_KEY + userId;
            couponRedisTemplate.delete(couponsKey);
            log.debug("删除用户 {} 的优惠券缓存", userId);
        } catch (Exception e) {
            log.error("删除用户 {} 的优惠券缓存失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 检查用户是否拥有指定优惠券
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @return 是否拥有
     */
    private boolean hasUserCoupon(Long userId, Integer couponId) {
        try {
            // 先从缓存中查找
            List<Map<String, Object>> cachedCoupons = getUserCouponsFromCache(userId);
            boolean existsInCache = cachedCoupons.stream()
                .anyMatch(coupon -> couponId.equals(coupon.get("id")));
            
            if (existsInCache) {
                return true;
            }
            
            // 缓存中没有，查询数据库
            com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserCoupons> wrapper =
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
            wrapper.eq(UserCoupons::getUserId, userId.intValue())
                   .eq(UserCoupons::getCouponId, couponId);
            return userCouponsMapper.selectCount(wrapper) > 0;
        } catch (Exception e) {
            log.error("检查用户 {} 是否拥有优惠券 {} 失败: {}", userId, couponId, e.getMessage());
            return false;
        }
    }
    
    /**
     * 更新用户优惠券缓存
     * @param userId 用户ID
     * @param newCoupon 新增的优惠券
     */
    private void updateUserCouponsCache(Long userId, Coupons newCoupon) {
        try {
            String couponsKey = RedisConstants.COUPONS_KEY + userId;

            // 获取现有缓存
            List<Map<String, Object>> existingCoupons = getUserCouponsFromCache(userId);

            // 检查是否已存在相同ID的优惠券
            boolean exists = existingCoupons.stream()
                .anyMatch(coupon -> newCoupon.getId().equals(coupon.get("id")));

            if (!exists) {
                // 添加新优惠券（转换为指定格式）
                List<Coupons> newCouponList = new ArrayList<>();
                newCouponList.add(newCoupon);
                List<Map<String, Object>> newCouponFormatted = convertCouponsToRequiredFormat(newCouponList);
                existingCoupons.addAll(newCouponFormatted);

                // 重新缓存，使用动态过期时间
                String couponsJson = objectMapper.writeValueAsString(existingCoupons);
                long expireSeconds = calculateCouponExpireTime(newCoupon);
                couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, expireSeconds, TimeUnit.SECONDS);

                log.debug("更新用户 {} 优惠券缓存，新增优惠券ID: {}", userId, newCoupon.getId());
            }
        } catch (Exception e) {
            log.error("更新用户 {} 优惠券缓存失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 将优惠券列表转换为指定的Redis存储格式
     * 只包含必需字段，时间转换为毫秒时间戳
     * @param coupons 优惠券列表
     * @return 转换后的格式化列表
     */
    private List<Map<String, Object>> convertCouponsToRequiredFormat(List<Coupons> coupons) {
        List<Map<String, Object>> formattedList = new ArrayList<>();
        for (Coupons coupon : coupons) {
            Map<String, Object> couponMap = new HashMap<>();

            // 只包含必需的字段
            couponMap.put("id", coupon.getId());
            couponMap.put("title", coupon.getTitle());
            couponMap.put("description", coupon.getDescription());
            couponMap.put("type", coupon.getType());
            couponMap.put("amount", coupon.getAmount());
            couponMap.put("minSpend", coupon.getMinSpend());

            // 处理时间字段 - 支持两种模式
            if (coupon.getStartTime() != null && coupon.getEndTime() != null) {
                // 指定时间段模式：直接使用数据库中的时间
                couponMap.put("startTime", coupon.getStartTime().getTime());
                couponMap.put("endTime", coupon.getEndTime().getTime());
            } else if (coupon.getValidHours() != null && coupon.getValidHours() > 0) {
                // 生效时长模式：使用当前时间作为开始时间，计算结束时间
                Date now = new Date();
                Date endTime = new Date(now.getTime() + coupon.getValidHours() * 3600L * 1000L);
                couponMap.put("startTime", now.getTime());
                couponMap.put("endTime", endTime.getTime());
            } else {
                // 兜底：使用默认时间范围（当前时间到30天后）
                Date now = new Date();
                Date endTime = new Date(now.getTime() + 30L * 24L * 3600L * 1000L); // 30天后
                couponMap.put("startTime", now.getTime());
                couponMap.put("endTime", endTime.getTime());
            }

            couponMap.put("status", coupon.getStatus());

            formattedList.add(couponMap);
        }
        return formattedList;
    }

    /**
     * 计算优惠券的Redis缓存过期时间
     * 根据设置的时长和优惠券是否过期来判断TTL
     * @param coupon 优惠券对象
     * @return 过期时间（秒）
     */
    private long calculateCouponExpireTime(Coupons coupon) {
        long expireSeconds = RedisConstants.NEW_USER_COUPON_TTL * 24 * 60 * 60; // 默认6天
        final long ONE_DAY_SECONDS = 24 * 60 * 60; // 一天的秒数
        final long MIN_TTL_SECONDS = 60 * 60; // 最小TTL：1小时

        try {
            // 优先使用优惠券的结束时间
            if (coupon.getEndTime() != null) {
                long endTimeMillis = coupon.getEndTime().getTime();
                long currentTimeMillis = System.currentTimeMillis();
                long diffSeconds = (endTimeMillis - currentTimeMillis) / 1000;

                if (diffSeconds > 0) {
                    if (diffSeconds < ONE_DAY_SECONDS) {
                        // 不足一天时：用结束时间减去当前时间
                        expireSeconds = Math.max(diffSeconds, MIN_TTL_SECONDS);
                    } else {
                        // 满一天的话：给Redis设置过期时间为对应时长
                        expireSeconds = diffSeconds;
                    }
                } else {
                    // 优惠券已过期，设置最小TTL
                    expireSeconds = MIN_TTL_SECONDS;
                }
            }
            // 如果有有效时长设置
            else if (coupon.getValidHours() != null && coupon.getValidHours() > 0) {
                long validSeconds = coupon.getValidHours() * 60 * 60;
                if (validSeconds < ONE_DAY_SECONDS) {
                    // 不足一天时：使用设置的时长
                    expireSeconds = Math.max(validSeconds, MIN_TTL_SECONDS);
                } else {
                    // 满一天的话：使用设置的时长
                    expireSeconds = validSeconds;
                }
            }

        } catch (Exception e) {
            log.warn("计算优惠券 {} 过期时间失败，使用默认值: {}", coupon.getId(), e.getMessage());
        }

        // 确保TTL不小于最小值
        return Math.max(expireSeconds, MIN_TTL_SECONDS);
    }

    /**
     * 计算多个优惠券的最优过期时间
     * @param coupons 优惠券列表
     * @return 过期时间（秒）
     */
    private long calculateOptimalExpireTime(List<Coupons> coupons) {
        if (coupons == null || coupons.isEmpty()) {
            return RedisConstants.NEW_USER_COUPON_TTL * 24 * 60 * 60; // 默认6天
        }

        // 找到最早过期的优惠券时间
        long minExpireSeconds = RedisConstants.NEW_USER_COUPON_TTL * 24 * 60 * 60;

        for (Coupons coupon : coupons) {
            long couponExpireSeconds = calculateCouponExpireTime(coupon);
            minExpireSeconds = Math.min(minExpireSeconds, couponExpireSeconds);
        }

        return minExpireSeconds;
    }

    /**
     * 查询所有发放的优惠券
     * @param userId 用户ID（可选，为null时查询所有用户）
     * @param status 优惠券状态（可选，为null时查询所有状态）1-未使用，2-已使用
     * @param couponId 优惠券ID（可选，为null时查询所有优惠券）
     * @return 发放的优惠券列表
     */
    public List<Map<String, Object>> queryDistributedCoupons(Long userId, Integer status, Integer couponId) {
        try {
            // 构建查询条件
            QueryWrapper<UserCoupons> queryWrapper = new QueryWrapper<>();
            if (userId != null) {
                queryWrapper.eq("user_id", userId.intValue());
            }
            if (status != null) {
                queryWrapper.eq("status", status);
            }
            if (couponId != null) {
                queryWrapper.eq("coupon_id", couponId);
            }

            // 查询用户优惠券记录
            List<UserCoupons> userCouponsList = userCouponsMapper.selectList(queryWrapper);

            if (userCouponsList.isEmpty()) {
                return new ArrayList<>();
            }

            // 获取所有相关的优惠券ID
            Set<Integer> couponIds = userCouponsList.stream()
                .map(UserCoupons::getCouponId)
                .collect(java.util.stream.Collectors.toSet());

            // 批量查询优惠券信息
            List<Coupons> couponsList = couponsMapper.selectBatchIds(couponIds);
            Map<Integer, Coupons> couponsMap = couponsList.stream()
                .collect(java.util.stream.Collectors.toMap(Coupons::getId, c -> c));

            // 组装结果
            List<Map<String, Object>> result = new ArrayList<>();
            for (UserCoupons userCoupon : userCouponsList) {
                Coupons coupon = couponsMap.get(userCoupon.getCouponId());
                if (coupon != null) {
                    Map<String, Object> item = new HashMap<>();

                    // 用户优惠券信息
                    item.put("userCouponId", userCoupon.getId());
                    item.put("userId", userCoupon.getUserId());
                    item.put("status", userCoupon.getStatus());
                    item.put("usedTime", userCoupon.getUsedTime());
                    item.put("orderId", userCoupon.getOrderId());
                    item.put("receivedAt", userCoupon.getCreatedAt());

                    // 优惠券详细信息
                    item.put("couponId", coupon.getId());
                    item.put("title", coupon.getTitle());
                    item.put("description", coupon.getDescription());
                    item.put("type", coupon.getType());
                    item.put("amount", coupon.getAmount());
                    item.put("minSpend", coupon.getMinSpend());
                    item.put("startTime", coupon.getStartTime());
                    item.put("endTime", coupon.getEndTime());
                    item.put("couponStatus", coupon.getStatus());
                    item.put("totalCount", coupon.getTotalCount());
                    item.put("limitPerUser", coupon.getLimitPerUser());
                    item.put("validHours", coupon.getValidHours());

                    result.add(item);
                }
            }

            log.info("查询发放优惠券完成，条件: userId={}, status={}, couponId={}, 结果数量: {}",
                userId, status, couponId, result.size());

            return result;

        } catch (Exception e) {
            log.error("查询发放优惠券失败，条件: userId={}, status={}, couponId={}: {}",
                userId, status, couponId, e.getMessage(), e);
            throw new RuntimeException("查询发放优惠券失败", e);
        }
    }

    /**
     * 从数据库获取用户所有有效优惠券
     * @param userId 用户ID
     * @return 用户优惠券列表
     */
    private List<Coupons> getUserAllCouponsFromDB(Long userId) {
        try {
            // 查询用户拥有的所有优惠券ID
            com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserCoupons> wrapper =
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
            wrapper.eq(UserCoupons::getUserId, userId.intValue())
                   .eq(UserCoupons::getStatus, 1); // 只查询未使用的优惠券

            List<UserCoupons> userCoupons = userCouponsMapper.selectList(wrapper);

            if (userCoupons.isEmpty()) {
                return new ArrayList<>();
            }

            // 获取优惠券详细信息
            List<Integer> couponIds = userCoupons.stream()
                .map(UserCoupons::getCouponId)
                .distinct()
                .toList();

            List<Coupons> coupons = couponsMapper.selectBatchIds(couponIds);

            // 过滤掉无效的优惠券（状态不为1的）
            return coupons.stream()
                .filter(coupon -> coupon.getStatus() == 1)
                .toList();

        } catch (Exception e) {
            log.error("从数据库获取用户 {} 的优惠券失败: {}", userId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
}
